package com.aliang.shopping.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.aliang.shopping.common.PageResult;
import com.aliang.shopping.common.Result;
import com.aliang.shopping.common.ResultCodeEnum;
import com.aliang.shopping.config.OssConfig;
import com.aliang.shopping.contact.ResultMsgContact;
import com.aliang.shopping.contact.SqlColumnConstant;
import com.aliang.shopping.exception.DataException;
import com.aliang.shopping.log.annotation.OperateLog;
import com.aliang.shopping.log.enums.OperateType;
import com.aliang.shopping.model.converter.BannerConverter;
import com.aliang.shopping.model.dto.banner.BannerInsertDTO;
import com.aliang.shopping.model.dto.banner.BannerQueryDTO;
import com.aliang.shopping.model.dto.banner.BannerUpdateDTO;
import com.aliang.shopping.model.dto.common.UpdateStatusDTO;
import com.aliang.shopping.model.enums.BannerAreaEnum;
import com.aliang.shopping.model.po.Banner;
import com.aliang.shopping.model.vo.banner.BannerFrontVO;
import com.aliang.shopping.model.vo.banner.BannerVO;
import com.aliang.shopping.security.PreventRepeatSubmit;
import com.aliang.shopping.service.BannerService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/banner")
@AllArgsConstructor
public class BannerController {

    private final BannerService bannerService;
    private final BannerConverter bannerConverter;
    private final OssConfig ossConfig;

    /**
     * 轮播图插入
     *
     * @param insertDTO
     * @return
     */
    @PostMapping("/insert")
    @ApiOperation("轮播图插入")
    @PreventRepeatSubmit
    @OperateLog(title = "轮播图插入", type = OperateType.INSERT)
    public Result<String> insertBanner(@RequestBody BannerInsertDTO insertDTO) {
        //必要字段校验
        if (BeanUtil.hasNullField(insertDTO) || StrUtil.hasBlank(insertDTO.getImage(), insertDTO.getToPath())) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        // 判断跳转路径是否已存在
        if (this.bannerService.count(
                new LambdaQueryWrapper<Banner>()
                        .eq(Banner::getToPath, insertDTO.getToPath())
        ) > 0) {
            throw new DataException(ResultCodeEnum.PATH_IS_EXIT);
        }
        //截取图片地址
        insertDTO.setImage(StrUtil.subAfter(insertDTO.getImage(), ossConfig.getUrl(), false));
        //转换数据
        Banner banner = this.bannerConverter.toPoByInsertDTO(insertDTO);
        this.bannerService.save(banner);

        return Result.ok(ResultMsgContact.INSERT_SUCCESS);
    }

    /**
     * 轮播图删除
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/del")
    @ApiOperation("轮播图删除")
    @PreventRepeatSubmit
    @OperateLog(title = "轮播图删除", type = OperateType.DELETE)
    public Result<String> delBanner(@RequestBody List<Long> ids) {
        this.bannerService.removeByIds(ids);
        return Result.ok(ResultMsgContact.DELETE_SUCCESS);
    }

    /**
     * 轮播图更改
     *
     * @param updateDTO
     * @return
     */
    @PutMapping("/update")
    @ApiOperation("轮播图更改")
    @PreventRepeatSubmit
    @OperateLog(title = "轮播图更改", type = OperateType.UPDATE)
    public Result<String> updateBanner(@RequestBody BannerUpdateDTO updateDTO) {
        //必要字段校验
        if (BeanUtil.hasNullField(updateDTO)) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        // 判断跳转路径是否已存在
        if (this.bannerService.count(
                new LambdaQueryWrapper<Banner>()
                        .eq(Banner::getToPath, updateDTO.getToPath())
                        .ne(Banner::getId, updateDTO.getId())
        ) > 0) {
            throw new DataException(ResultCodeEnum.PATH_IS_EXIT);
        }
        //截取图片地址
        updateDTO.setImage(StrUtil.subAfter(updateDTO.getImage(), ossConfig.getUrl(), false));
        //转换数据
        Banner banner = this.bannerConverter.toPoByUpdateDTO(updateDTO);
        this.bannerService.updateById(banner);
        return Result.ok(ResultMsgContact.UPDATE_SUCCESS);
    }

    /**
     * 轮播图状态更改
     *
     * @param updateDTO
     * @return
     */
    @PutMapping("/update_static")
    @ApiOperation("轮播图状态更改")
    @PreventRepeatSubmit
    @OperateLog(title = "轮播图状态更改", type = OperateType.UPDATE_STATUS)
    public Result<String> updateBannerStatic(@RequestBody UpdateStatusDTO updateDTO) {
        //必要字段校验
        if (BeanUtil.isEmpty(updateDTO)) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //转换数据
        Banner banner = this.bannerConverter.toPoByUpdateStaticDTO(updateDTO);
        this.bannerService.updateById(banner);
        return Result.ok(ResultMsgContact.UPDATE_SUCCESS);
    }

    /**
     * 轮播图分页搜索
     */
    @GetMapping("/getPage")
    @ApiOperation("轮播图分页搜索")
    public Result<PageResult<BannerVO>> queryBannerPage(BannerQueryDTO pageDTO) {
        //必要字段校验
        if (ObjectUtil.hasNull(pageDTO.getPageSize(), pageDTO.getPageNum())) {
            throw new DataException(ResultCodeEnum.DATA_LACK);
        }
        //查询数据
        PageResult<BannerVO> result = this.bannerService.selectPage(pageDTO);
        return Result.ok(result);
    }


    /**
     * 获取前台轮播图
     */
    @GetMapping("/getFrontBanner")
    @ApiOperation("获取前台轮播图")
    public Result<BannerFrontVO> getFrontBanner() {
        //获取全部轮播图
        List<Banner> list = this.bannerService.list(
                new LambdaQueryWrapper<Banner>()
                        .eq(Banner::getStatus, SqlColumnConstant.STATUS_OK)
        );
        // 设置完整路径
        list.forEach(item -> item.setImage(ossConfig.getUrl() + item.getImage()));
        if (list.isEmpty()) {
            return Result.fail();
        }
        //根据区域分组
        Map<Integer, List<Banner>> map = list.stream().collect(Collectors.groupingBy(Banner::getAreaNum));
        BannerFrontVO result = new BannerFrontVO();
        result.setOneBanner(this.bannerConverter.toBannerFrontList(map.get(BannerAreaEnum.ONE.getCode())));
        result.setTwoBanner(this.bannerConverter.toBannerFrontList(map.get(BannerAreaEnum.TWO.getCode())));
        result.setThreeBanner(this.bannerConverter.toBannerFrontList(map.get(BannerAreaEnum.THREE.getCode())));
        // 返回数据
        return Result.ok(result);
    }
}
